﻿using Newtonsoft.Json;
using System.Diagnostics;
using System.Windows;
using VisionDesigner;
using VisionDesigner.PositionFix;
using VM.Common.Enums;
using VM.Common.Helper;
using VM.Start.Common.Hik;
using VM.Start.Common.Provide;
using VM.Start.Controls;
using VM.Start.Models;
using VM.Start.Services;

namespace VM.Start.Core
{
    [JsonObject(MemberSerialization.OptOut)]
    public abstract class ModuleBase : NotifyPropertyBase
    {
        #region  属性
        /// <summary>
        /// 输入图像链接文本
        /// </summary>
        public string _InputImageLinkText;
        [Newtonsoft.Json.JsonIgnore]
        public string InputImageLinkText
        {
            get { return _InputImageLinkText; }
            set
            {
                _InputImageLinkText = value;
                RaisePropertyChanged();
                GetDispImage(InputImageLinkText, true);
            }
        }

        private Visibility _PositionFixVisible = Visibility.Collapsed;
        public Visibility PositionFixVisible
        {
            get { return _PositionFixVisible; }
            set { Set(ref _PositionFixVisible, value); }
        }

        /// <summary>位置修正 </summary>
        private bool _IsPositionFix = false;
        public bool IsPositionFix
        {
            get
            {
                return _IsPositionFix;
            }
            set
            {
                Set(ref _IsPositionFix, value);
                if (_IsPositionFix)
                {
                    PositionFixVisible = Visibility.Visible;
                }
                else
                {
                    PositionFixVisible = Visibility.Collapsed;
                }
            }
        }

        /// <summary>
        /// 位置修正
        /// </summary>
        public string _PositionFixText;
        [Newtonsoft.Json.JsonIgnore]
        public string PositionFixText
        {
            get { return _PositionFixText; }
            set
            {
                _PositionFixText = value;
                RaisePropertyChanged();
                IsPositionFix = PositionFixText != null ? true : false;
                GetPositionFix(PositionFixText);
            }
        }

        /// <summary>
        /// 输出画布
        /// </summary>
        private string _InputModuleLinkText;
        [Newtonsoft.Json.JsonIgnore]
        public string InputModuleLinkText
        {
            get { return _InputModuleLinkText; }
            set
            {
                _InputModuleLinkText = value;
                RaisePropertyChanged();
            }
        }

        public Guid ModuleGuid = Guid.NewGuid();

        [Newtonsoft.Json.JsonIgnore]
        private CMvdImage _DispImage;
        [Newtonsoft.Json.JsonIgnore]
        public CMvdImage DispImage
        {
            get => _DispImage;
            set => _DispImage = value;
        }

        [Newtonsoft.Json.JsonIgnore]
        private VMDisplayControl _mWindowH;
        [Newtonsoft.Json.JsonIgnore]
        public VMDisplayControl mWindowH
        {
            get
            {
                if (_mWindowH == null)
                {
                    _mWindowH = new VMDisplayControl();
                }
                return _mWindowH;
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        public CPositionFixTool PositionFixTool;

        private Project _Prj;
        public Project Prj
        {
            get
            {
                if (_Prj == null)
                {
                    _Prj = Solution.Ins.GetProjectById(ModuleParam.ProjectID);
                }
                return _Prj;
            }
            set { _Prj = value; }
        }

        /// <summary>
        /// 模块参数
        /// </summary>
        public ModuleParam _ModuleParam;
        public ModuleParam ModuleParam
        {
            get
            {
                if (_ModuleParam == null)
                {
                    _ModuleParam = new ModuleParam();
                }
                return _ModuleParam;
            }
            set { _ModuleParam = value; }
        }

        [Newtonsoft.Json.JsonIgnore]
        public ModuleViewBase ModuleView { get; set; }

        /// <summary>
        /// 计时器
        /// </summary>
        [Newtonsoft.Json.JsonIgnore]
        private Stopwatch _Stopwatch;
        [Newtonsoft.Json.JsonIgnore]
        public Stopwatch Stopwatch
        {
            get
            {
                if (_Stopwatch == null)
                {
                    _Stopwatch = new Stopwatch();
                }
                return _Stopwatch;
            }
            set { _Stopwatch = value; }
        }
        [Newtonsoft.Json.JsonIgnore]
        public bool ClosedView = false;
        /// <summary>
        /// 取消等待流程
        /// </summary>
        [Newtonsoft.Json.JsonIgnore]
        public bool CancelWait = false;
        #endregion
        #region 方法
        /// <summary>
        /// 加载视图
        /// </summary>
        public virtual void Loaded()
        {
            if (ModuleView != null)
            {
                ModuleView.IsClosed = false;
                // 强制刷新界面
                ModuleView.Dispatcher.Invoke(() =>
                {
                    ModuleView.InvalidateVisual(); // 重绘界面
                });
            }

            if (DispImage == null)
            {
                SetDefaultLink();
                if (InputImageLinkText == null) return;
            }
            GetDispImage(InputImageLinkText, true);
            if (PositionFixText != null)
            {
                GetPositionFix(PositionFixText);
            }
        }

        public virtual void CloseView()
        {
            if (ModuleView != null)
            {
                ModuleView.Close();
            }
        }

        public virtual void Init() { }

        /// <summary>
        /// 执行模块
        /// </summary>
        /// <returns></returns>
        public abstract bool ExeModule();
        public abstract bool ExeModule(string TemplateName);

        /// <summary>
        /// 添加模块输出参数
        /// </summary>
        /// <returns></returns>
        public virtual void AddOutputParams()
        {
            AddOutputParam("状态", "bool", ModuleParam.Status == eRunStatus.OK ? true : false);
            AddOutputParam("时间", "int", ModuleParam.ElapsedTime);
        }

        /// <summary>
        /// 输出变量
        /// </summary>
        protected void AddOutputParam(string varName, string varType, object obj, string note = "")
        {
            this.Prj.AddOutputParam(this.ModuleParam, varName, varType, obj, note);
        }
        /// <summary>
        /// 更改模块运行状态
        /// </summary>
        /// <param name="runStatus"></param>
        protected void ChangeModuleRunStatus(eRunStatus runStatus)
        {
            ModuleParam.Status = runStatus;
            Stopwatch.Stop();
            ModuleParam.ElapsedTime = Stopwatch.ElapsedMilliseconds;
            if (runStatus == eRunStatus.OK)
            {
                Logger.AddLog(
                    $"流程[{Solution.Ins.GetProjectById(ModuleParam.ProjectID).ProjectInfo.ProcessName}]执行[{ModuleParam.ModuleName}]模块成功，耗时{ModuleParam.ElapsedTime}ms.", eMsgType.Success
                );
            }
            else
            {
                if (DispImage == null)
                {
                    DispImage = new RImage();
                }
            }
            AddOutputParams();
        }

        public virtual void SetDefaultLink() { }

        public void GetDispImage(string imageLinkText, bool isMono8 = false)
        {
            if (imageLinkText == null)
                return;
            VarModel var = Prj.GetParamByName(imageLinkText);
            if (var == null)
                return;
            object image = var.Value;
            if (image == null)
                return;
            if (image is CMvdImage)
            {
                DispImage = (CMvdImage)image;
                if (DispImage != null && isMono8 && !DispImage.IsEmpty && DispImage.PixelFormat != MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08)
                {
                    DispImage = DispImage.Clone();
                    DispImage.ConvertImagePixelFormat(MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08);
                }
                mWindowH.Image = DispImage;
            }
        }

        public void GetPositionFix(string PositionFixText)
        {
            if (PositionFixText == null)
                return;
            VarModel var = Prj.GetParamByName(PositionFixText);
            if (var == null)
                return;
            object positonfix = var.Value;
            if (positonfix == null)
                return;
            if (positonfix is CPositionFixTool)
            {
                PositionFixTool = (CPositionFixTool)positonfix;
            }
        }

        #endregion
    }
}
